from get_total_marketcap_via_http import get_total_marketcap_amount_via_http
import os
from quant_researcher.quant.project_tool.time_tool import get_today, calc_date_diff,date_shifter, str_to_timestamp
import pandas as pd
from fetch_binance_kline import fetch_binance_kline
from quant_researcher.quant.datasource_fetch.crypto_api.coingecko import CoinGeckoAPI
import time


def get_cex_spot_amount_coinmarketcap():
    # 从CMC上获取中心化交易所交易额
    data = get_total_marketcap_amount_via_http(exclude_btc=False)
    file_path = os.path.join("G:/", r'trading_data')
    file_name = os.path.join(file_path, f'cex_total_spot_amount_coinmarketcap')
    data.to_excel(f'{file_name}.xlsx')


def get_cex_total_spot_amount_biance_BTCUSD():
    # 从binance获取币安BTC兑稳定币的相关现货交易额
    end_date = get_today(marker='with_n_dash')
    file_path = os.path.join("G:/", r'trading_data')
    file_name = os.path.join(file_path, f'cex_total_spot_amount_biance_BTCUSD')
    if os.path.exists(f'{file_name}.xlsx'):
        history_binance_amount = pd.read_excel(f'{file_name}.xlsx', index_col='date')
        start_date = history_binance_amount.index[-1]
        if calc_date_diff(start_date, end_date) < 3:
            start_date = date_shifter(before=start_date, step='days', how_many=-3)
    else:
        start_date = '2017-01-01'
    start = str_to_timestamp(start_date, tz_str='+0800')
    end = str_to_timestamp(end_date, tz_str='+0800')
    binance_BTCUSDT = fetch_binance_kline("BTCUSDT", start, end, '1d')
    print('从binance获取BTCUSDT交易额成功')
    # binance_BTCBUSD = fetch_binance_kline("BTCBUSD", start, end, '1d')
    # print('从binance获取BTCBUSD交易额成功')
    binance_BTCUSDC = fetch_binance_kline("BTCUSDC", start, end, '1d')
    print('从binance获取BTCUSDC交易额成功')
    # binance_BTCBUSD = pd.Series(binance_BTCBUSD['amount'], index=binance_BTCUSDT.index).fillna(0)
    if binance_BTCUSDC is not None:
        binance_BTCUSDC = pd.Series(binance_BTCUSDC['amount'], index=binance_BTCUSDT.index).fillna(0)
        # amount = binance_BTCUSDT['amount'] + binance_BTCBUSD + binance_BTCUSDC
        amount = binance_BTCUSDT['amount'] + binance_BTCUSDC
    else:
        # amount = binance_BTCUSDT['amount'] + binance_BTCBUSD
        amount = binance_BTCUSDT['amount']

    amount_df = pd.DataFrame(amount)
    if os.path.exists(f'{file_name}.xlsx'):
        previous_date = date_shifter(amount.index[0], step='days', how_many=-1)
        amount_df = pd.concat([history_binance_amount.loc[:previous_date, ], amount_df.iloc[:, ]])  # 最新一天数据为当天，数据还不完整
    amount_df.to_excel(f'{file_name}.xlsx')


def get_cex_total_spot_amount_each_exchange_coingecko():
    ### 从coingecko获取主流交易所现货交易额历史数据 ###
    file_path = os.path.join("G:/", r'trading_data')
    cg = CoinGeckoAPI()
    # spot_exchange_id_list = ['binance', 'gdax', 'ftx_spot', 'okex', 'huobi', 'gate', 'kucoin', 'crypto_com', 'bitfinex']
    spot_exchange_id_list = ['binance', 'gdax', 'okex', 'huobi', 'gate', 'kucoin', 'crypto_com', 'bitfinex', 'bybit_spot']
    exchange_volume_df_list = []
    file_name = os.path.join(file_path, f'cex_total_spot_amount_each_exchange_coingecko')
    if os.path.exists(f'{file_name}.xlsx'):
        days = 30
    else:
        days = 365
    for exchange_id in spot_exchange_id_list:
        print(f'开始获取{exchange_id}现货交易额数据')
        exchange_volume = cg.get_exchanges_volume_chart_by_id(id=exchange_id, days=days)['amount']
        print(f'{exchange_id}现货交易额数据获取成功')
        if exchange_id == 'gdax':
            exchange_name = 'coinbase'
        elif exchange_id == 'ftx_spot':
            exchange_name = 'ftx'
        else:
            exchange_name = exchange_id
        exchange_volume = exchange_volume[~exchange_volume.index.duplicated(keep="first")]
        exchange_volume.name = exchange_name
        exchange_volume_df_list.append(exchange_volume)
        time.sleep(10)

    spot_exchange_volume_df = pd.concat(exchange_volume_df_list, axis=1)
    if os.path.exists(f'{file_name}.xlsx'):
        hist_spot_exchange_volume_df = pd.read_excel(f'{file_name}.xlsx', index_col='date')
        previous_date = date_shifter(spot_exchange_volume_df.index[0], step='days', how_many=-1)
        spot_exchange_volume_df = pd.concat([hist_spot_exchange_volume_df.loc[:previous_date, ], spot_exchange_volume_df.iloc[:-1, ]])  # 最新一天数据为当天，数据还不完整
    spot_exchange_volume_df.to_excel(f'{file_name}.xlsx')


def get_cex_total_deri_amount_each_exchange_coingecko():
    ## 从coingecko获取主流衍生品交易所衍生品交易额历史数据 ###
    cg = CoinGeckoAPI()
    file_path = os.path.join("G:/", r'trading_data')
    # deri_exchange_id_list = ['binance', 'okex', 'bybit', 'ftx', 'kucoin', 'crypto_com', 'huobi', 'gate', 'bitfinex', 'kraken', 'bitmex']
    deri_exchange_id_list = ['binance', 'okex', 'bybit', 'kucoin', 'crypto_com', 'huobi', 'gate', 'bitfinex', 'kraken', 'bitmex']
    deri_exchange_volume_df_list = []
    # deri_exchange_oi_df_list = []
    file_name = os.path.join(file_path, f'cex_total_deri_amount_each_exchange_coingecko')
    if os.path.exists(f'{file_name}.xlsx'):
        days = 30
    else:
        days = 365
    for deri_exchange_id in deri_exchange_id_list:
        print(f'开始获取{deri_exchange_id}衍生品交易额数据')
        deri_exchange_data = cg.get_derivative_exchanges_volume_by_id(id=deri_exchange_id, days=days)
        deri_exchange_volume = deri_exchange_data['amount']
        print(f'{deri_exchange_id}衍生品交易额数据获取成功')
        deri_exchange_volume = deri_exchange_volume[~deri_exchange_volume.index.duplicated(keep="first")]
        deri_exchange_volume[deri_exchange_volume > 100 * deri_exchange_volume.median()] = None  # 剔除掉异常值
        deri_exchange_volume.name = deri_exchange_id
        deri_exchange_volume_df_list.append(deri_exchange_volume)

        # deri_exchange_oi = deri_exchange_data['open_interest']
        # deri_exchange_oi = deri_exchange_oi[~deri_exchange_oi.index.duplicated(keep="first")]
        # deri_exchange_oi.name = deri_exchange_id
        # deri_exchange_oi_df_list.append(deri_exchange_oi)
        time.sleep(10)

    deri_exchange_volume_df = pd.concat(deri_exchange_volume_df_list, axis=1)
    if os.path.exists(f'{file_name}.xlsx'):
        hist_deri_exchange_volume_df = pd.read_excel(f'{file_name}.xlsx', index_col='Unnamed: 0')
        previous_date = date_shifter(deri_exchange_volume_df.index[0], step='days', how_many=-1)
        deri_exchange_volume_df = pd.concat([hist_deri_exchange_volume_df.loc[:previous_date, ], deri_exchange_volume_df.iloc[:-1, ]])  # 最新一天数据为当天，数据还不完整
    deri_exchange_volume_df.to_excel(f'{file_name}.xlsx')

    # # 各交易所的期货开仓量汇总
    # deri_exchange_oi_df = pd.concat(deri_exchange_oi_df_list, axis=1)
    # file_name = os.path.join(file_path, f'cex_total_deri_oi_each_exchange_coingecko')
    # if os.path.exists(f'{file_name}.xlsx'):
    #     hist_deri_exchange_oi_df = pd.read_excel(f'{file_name}.xlsx', index_col='date')
    #     deri_exchange_oi_df = pd.concat([hist_deri_exchange_oi_df, deri_exchange_oi_df])
    #     deri_exchange_oi_df = deri_exchange_oi_df[~deri_exchange_oi_df.index.duplicated(keep='last')]
    #     deri_exchange_oi_df.to_excel(f'{file_name}.xlsx')
    # else:
    #     deri_exchange_oi_df.to_excel(f'{file_name}.xlsx')


    time.sleep(5)


def get_dex_total_spot_amount_coingecko():
    # 获取去中心化交易所交易额
    # dex_list = ['Uniswap (v3)', 'Curve Finance', 'PancakeSwap (v2)', 'Orca', 'Biswap', 'Uniswap (v2)', 'Jupiter', 'Uniswap (Polygon)', 'SpookySwap', 'Serum DEX',
    #             'Raydium', 'Sushiswap', 'Trader Joe', 'MM Finance', 'Osmosis', 'Sunswap (v1)', 'Dodo (Polygon)', 'Saber', 'DeFiChain DEX', 'Balancer (v2)', 'Quickswap',
    #             'THORChain', 'Uniswap (Arbitrum One)', 'Dodo (BSC)', 'Balancer (v1)', 'Curve (Factory Pools)', 'Sushiswap (Arbitrum One)', 'SpiritSwap', 'Bancor Network', 'SunSwap (v2)',
    #             'Shibaswap', 'KyberSwap (Polygon)', 'Loopring AMM', 'Uniswap (Optimism)', 'Astroport', 'Binance DEX', 'Uniswap (v1)',
    #             'dYdX', 'Honeyswap', 'Sushiswap (Polygon POS)', 'ApeSwap', 'BabySwap', 'Shibaswap', 'Sushiswap (Avalanche)',
    #             'Balancer (Polygon)', 'Sushiswap (Harmony)', 'Balancer (Arbitrum)', 'Dodo (Arbitrum)', 'Sushiswap (Fantom)', 'Honeyswap']
    cg = CoinGeckoAPI()
    file_path = os.path.join("G:/", r'trading_data')
    dex_exchange_id_list = \
        ['uniswap-bsc', 'uniswap_v2', 'uniswap_v3', 'uniswap_v3_arbitrum', 'uniswap-v3-avalanche', 'uniswap_v3_optimism', 'uniswap_v3_polygon_pos',
         'curve_arbitrum', 'curve_ethereum', 'curve_optimism',
         'apex_pro', 'maverick_protocol', 'ferro-protocol', 'openocean_finance', 'jupiter', 'orca', 'thorwallet', 'thorswap', 'woofi', 'pulsex', 'syncswap',
         'balancer-v1', 'balancer-v2', 'balancer_arbitrum',
         'sushiswap', 'sun_io',
         'pancakeswap_aptos', 'pancakeswap_ethereum', 'pancakeswap_new', 'pancakeswap_stableswap', 'pancakeswap-v3-bsc', 'pancakeswap-v3-ethereum',
         'dodo', 'dodo_arbitrum', 'dodo_bsc', 'dodo_polygon',
         'traderjoe', 'traderjoe-v2-1-arbitrum', 'traderjoe-v2-1-avalanche', 'traderjoe-v2-1-bsc', 'traderjoe-v2-arbitrum', 'traderjoe-v2-avalanche', 'traderjoe-v2-bsc',
         'quickswap', 'quickswap-polygon-zkevm', 'quickswap_v3',
         ]

    # dex_list = list(set(dex_list))
    # dex_list.sort()
    # cg = CoinGeckoAPI()
    # exchange_list = cg.get_exchanges_id_name_list()
    # file_name = os.path.join(file_path, f'coingecko_exchange_list')
    # exchange_list.to_excel(f'{file_name}.xlsx')
    # dex_exchange_id_list = []
    # for index, row in exchange_list.iterrows():
    #     name = row['name']
    #     id = row['id']
    #     if name in dex_list:
    #         dex_exchange_id_list.append(id)

    dex_exchange_volume_list = []
    for dex_exchange_id in dex_exchange_id_list:
        print(f'开始获取{dex_exchange_id}的交易额数据')
        try:
            exchange_volume_df = cg.get_exchanges_volume_chart_by_id(id=dex_exchange_id, days=30)
        except:
            print(f'获取{dex_exchange_id}的交易额数据失败')
        else:
            exchange_volume_df = exchange_volume_df[~exchange_volume_df.index.duplicated(keep='first')]
            exchange_volume_series = exchange_volume_df['amount']
            exchange_volume_series.name = dex_exchange_id
            dex_exchange_volume_list.append(exchange_volume_series)
            print(f'获取{dex_exchange_id}的交易额数据成功')
            time.sleep(8)

    dex_exchange_volume_df = pd.concat(dex_exchange_volume_list, axis=1)
    dex_exchange_volume_df.sort_index(inplace=True)
    dex_exchange_volume_df['total'] = dex_exchange_volume_df.sum(axis=1)
    file_name = os.path.join(file_path, f'dex_total_spot_amount_coingecko')
    hist_dex_exchange_volume_df = pd.read_excel(f'{file_name}.xlsx', index_col='date')
    previous_date = date_shifter(dex_exchange_volume_df.index[0], step='days', how_many=-1)
    dex_exchange_volume_df = pd.concat([hist_dex_exchange_volume_df.loc[:previous_date, ], dex_exchange_volume_df.iloc[:-1, ]])  # 最新一天数据为当天，数据还不完整
    dex_exchange_volume_df.to_excel(f'{file_name}.xlsx')


def get_exchange_trading_volume():
    get_cex_spot_amount_coinmarketcap()
    get_cex_total_spot_amount_biance_BTCUSD()
    get_cex_total_spot_amount_each_exchange_coingecko()
    get_cex_total_deri_amount_each_exchange_coingecko()
    get_dex_total_spot_amount_coingecko()


if __name__ == '__main__':
    get_exchange_trading_volume()